#include <iostream>
#include <boost/type_traits.hpp>
using namespace std;
using namespace boost;

struct nt {
    typedef nt type;
    enum { value = 0 };
};

template < typename T0, 
           typename T1 = nt, 
           typename T2 = nt, 
           typename T3 = nt,
           typename T4 = nt>
struct mpl_vector {
    typedef T0 type0;
    typedef T1 type1;
    typedef T2 type2;
    typedef T3 type3;
    typedef T4 type4;
};

template < typename V , int N>
struct at_c {
    typedef nt type;
};

#define AT_C(num) \
    template <typename V> \
    struct at_c <V,num> { \
        typedef typename V::type##num type; \
    };

AT_C(0)
AT_C(1)
AT_C(2)
AT_C(3)

#undef AT_C

template < typename V, typename T >
struct mpl_push_front {
    struct _vec {
        typedef T type0;
        typedef typename V::type0 type1;
        typedef typename V::type1 type2;
        typedef typename V::type2 type3;
        typedef typename V::type3 type4;
    };
    typedef _vec type;
};

int main()
{
    cout << "--- Start ---" << endl;
    typedef mpl_vector<int, double, string>  mvec;
    cout << is_same<at_c<mvec, 2>::type, string>::value << endl;
    cout << is_same<at_c<mvec, 1>::type, double>::value << endl;
    cout << is_same<at_c<mvec, 1>::type, int>::value << endl;
    cout << is_same<at_c<mvec, 3>::type, int>::value << endl;

    cout << "---------" << endl;
    typedef mpl_push_front<mvec, char>::type n_vec;
    cout << is_same< at_c<n_vec, 1>::type, char>::value << endl;
    
    cout << "--- End ---" << endl;
    return 0;
}
